-
Notifications
You must be signed in to change notification settings - Fork 2
fix: add network error retry for transfer polling #763
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
from the Logs |
| consecutiveErrors++ | ||
| Logger.warn( | ||
| "Failed to fetch order '$orderId' (attempt $consecutiveErrors/$MAX_CONSECUTIVE_ERRORS)", | ||
| e = it, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to CLAUDE.md:
NEVER add
e =named parameter to Logger calls
The Logger.warn call should pass the throwable without the named parameter syntax.
| e = it, | |
| Logger.warn( | |
| "Failed to fetch order '$orderId' (attempt $consecutiveErrors/$MAX_CONSECUTIVE_ERRORS)", | |
| it, | |
| context = TAG | |
| ) |
| @Test | ||
| fun `refreshOrders returns failure when server throws`() = test { | ||
| sut = createSut() | ||
| wheneverBlocking { coreService.blocktank.orders(refresh = true) }.thenThrow(RuntimeException("Network error")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to CLAUDE.md:
NEVER use
wheneverBlockingin unit test expression body functions wrapped in a= test {}lambda
ALWAYS wrap unit testssetUpmethods mocking suspending calls withrunBlocking, e.gsetUp() = runBlocking {}
Move the mock setup to the setUp method using runBlocking instead of using wheneverBlocking inside the test expression body.
| @Test | ||
| fun `getOrder returns failure when refresh fails`() = test { | ||
| sut = createSut() | ||
| wheneverBlocking { coreService.blocktank.orders(refresh = true) }.thenThrow(RuntimeException("Network error")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to CLAUDE.md:
NEVER use
wheneverBlockingin unit test expression body functions wrapped in a= test {}lambda
ALWAYS wrap unit testssetUpmethods mocking suspending calls withrunBlocking, e.gsetUp() = runBlocking {}
Move the mock setup to the setUp method using runBlocking instead of using wheneverBlocking inside the test expression body.
| consecutiveErrors++ | ||
| Logger.warn( | ||
| "Failed to fetch order '$orderId' (attempt $consecutiveErrors/$MAX_CONSECUTIVE_ERRORS)", | ||
| e = it, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The named parameter e = should not be used in Logger calls.
CLAUDE.md Rule:
NEVER add
e =named parameter to Logger calls
Reference: CLAUDE.md:180
Fix:
| e = it, | |
| it, |
| @Test | ||
| fun `refreshOrders returns failure when server throws`() = test { | ||
| sut = createSut() | ||
| wheneverBlocking { coreService.blocktank.orders(refresh = true) }.thenThrow(RuntimeException("Network error")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wheneverBlocking call should not be used inside = test {} expression body functions.
CLAUDE.md Rule:
NEVER use
wheneverBlockingin unit test expression body functions wrapped in a= test {}lambdaALWAYS wrap unit tests
setUpmethods mocking suspending calls withrunBlocking, e.gsetUp() = runBlocking {}
Reference: CLAUDE.md:205-206
Suggested Fix:
Move the wheneverBlocking mock setup to the setUp() method wrapped in runBlocking, as shown in the existing tests in this file (see lines 42-49). Both new test methods (refreshOrders returns failure when server throws and getOrder returns failure when refresh fails) need this change.
Example pattern from existing tests:
@Before
fun setUp() = runBlocking {
wheneverBlocking { coreService.blocktank.orders(refresh = true) }.thenThrow(RuntimeException("Network error"))
}|
draft to apply suggestions |
Fixes #608
This PR adds network error resilience to the transfer-to-spending polling mechanism by distinguishing between transient network failures and permanent order errors.
Description
.fold()instead of.getOrNull()to properly handleResultfailuresPreview
Screen_recording_20260206_132910.mp4
QA Notes
To facilitate the simulation, you can put a breakpoint in the line and then disable internet
1. Normal transfer flow (regression)
2. Network error recovery
3. Persistent network failure